package com.qf.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.Mapper.OrderMapper;
import com.qf.entity.Order;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.ExchangeBuilder;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.nio.charset.Charset;
import java.util.Map;

/**
 * 作者：大狗
 * 时间：2021/7/13 14:56
 */
@Service
@Transactional
public class ConsumeServiceImpl {

    private static final String MESSAGE_ID_KEY_PREFIX = "msg_id_key_";
    private static final String DEAD_LETTER_QUEUE = "pay_dead_letter_queue";
    private static final String DEAD_LETTER_EXCHANGE = "pay_dead_letter_exchange";
    private static final String DEAD_LETTER_ROUTING_KEY = "pay_dead_letter_routing_key";

    private StringRedisTemplate redisTemplate;
    private ConnectionFactory factory;
    private OrderMapper orderMapper;

    public ConsumeServiceImpl(StringRedisTemplate redisTemplate, ConnectionFactory factory) {
        this.redisTemplate = redisTemplate;
        this.factory = factory;
    }

    @PostConstruct
    public void initDeadLetterQueueAndExchange() {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(factory);
        // 这是Spring中实例化一个队列的方式
        org.springframework.amqp.core.Queue queue = QueueBuilder.durable(DEAD_LETTER_QUEUE).build();
        rabbitAdmin.declareQueue(queue); //表示将实例化的queue写入到 RabbitMQ 中

        // 创建一个交换机
        org.springframework.amqp.core.Exchange exchange = ExchangeBuilder.directExchange(DEAD_LETTER_EXCHANGE).build();
        rabbitAdmin.declareExchange(exchange);

        // noargs() 表示绑定的时候没有任何的参数
        Binding binding = BindingBuilder.bind(queue).to(exchange).with(DEAD_LETTER_ROUTING_KEY).noargs();
        rabbitAdmin.declareBinding(binding);
    }
    @RabbitListener(
            bindings = @QueueBinding(
                    value =  @Queue(
                            name = "pay_queue",
                            durable = "true",
                            arguments = {
                                    @Argument(name = "x-dead-letter-exchange", value = DEAD_LETTER_EXCHANGE),
                                    @Argument(name = "x-dead-letter-routing-key", value = DEAD_LETTER_ROUTING_KEY)
                            }
                    ),
                    exchange = @Exchange(name = "pay_exchange"),
                    key = {"pay_key"}
            )
    )
    public void receiveMessage(org.springframework.amqp.core.Message message){
//        String correlationId = message.getMessageProperties().getCorrelationId();
        byte[] bs = message.getBody();
        String msgString = new String(bs, Charset.defaultCharset());
        // 反序列化
        Map<String,String> map = JSONObject.parseObject(msgString, Map.class);
        //获取订单编号
        String orderId = map.get("out_trade_no");
        //查询订单
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("order_id",orderId);
        Order order = orderMapper.selectOne(queryWrapper);
        if(order.getStatus() != 1){//表示未支付且超时
            orderMapper.delete(queryWrapper);//删除超时订单
        }

//        boolean isExists = redisTemplate.hasKey(MESSAGE_ID_KEY_PREFIX + correlationId);
//        if(!isExists) {  // 表示没有被消费过,
//            byte[] bs = message.getBody();
//            String msgString = new String(bs, Charset.defaultCharset());
//            // 反序列化
//            Map map = JSONObject.parseObject(msgString, Map.class);
//            //此处进行数据消费操作（数据库插入等）
//
//            redisTemplate.opsForValue().set(MESSAGE_ID_KEY_PREFIX + correlationId, correlationId, 15, TimeUnit.MINUTES);
//        }
    }

}
